#import "XMWebViewController.h"
#import <WebKit/WebKit.h>
#import "NSHTTPCookie+Utils.h"
#import "NSHTTPCookieStorage+Utils.h"
#import "XMLoginManager.h"
#import "YHAESHelper.h"
#import "YHRSAHelper.h"

#import "XMRechargeViewController.h"
#import "XMRealViewController.h"
#import "XMInviteViewController.h"
#import "XMBindPhoneLoginViewController.h"
#import "XMTaskViewController.h"
#import "XMIntimacyViewController.h"

@interface XMWebViewController () <WKNavigationDelegate, WKUIDelegate, WKScriptMessageHandler>
@property (nonatomic, strong) WKWebView *webView;
@property (nonatomic, strong) UIProgressView *progressView;
@end


@implementation XMWebViewController

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    self.navigationController.navigationBar.hidden = NO;
    [self.webView.configuration.userContentController addScriptMessageHandler:self name:@"gotoActivity"];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];
    [self.webView.configuration.userContentController removeScriptMessageHandlerForName:@"gotoActivity"];
}

- (void)viewDidLoad {
    [super viewDidLoad];
    if (self.needClearCache) {
        [self clearCache];
    }
    [self setupSubviews];
    if (self.needSetCookie) {
        [self updateWebViewCookie];
    }
}

#pragma mark - setupSubviews
- (void)setupSubviews {
    [self.navLeft2Btn setTitle:self.titleStr forState:UIControlStateNormal];
    
    [self.view addSubview:self.progressView];
    [self.view insertSubview:self.webView belowSubview:self.progressView];
    if (self.urlStr.length > 0) {
        self.urlStr = [self.urlStr stringByReplacingOccurrencesOfString:@" " withString:@""];
        self.urlStr = [self.urlStr stringByReplacingOccurrencesOfString:@"\r\n" withString:@""];
        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:self.urlStr]];
        if (self.needSetCookie) {
            [self.webView loadRequest:[self fixRequest:request]];
        } else {
            [self.webView loadRequest:request];
        }
    }
    if (@available(iOS 11.0, *)) {
        self.webView.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
    } else {
        self.edgesForExtendedLayout = UIRectEdgeNone;
    }
}

- (void)backAction {
    if ([self.webView canGoBack]) {
        [self.webView goBack];
        return;
    } else {
        [super backAction];
    }
}

- (void)webviewGoBack {
    [self.webView evaluateJavaScript:@"jsGobackBeforePage()" completionHandler:nil];
}

#pragma mark - WKNavigationDelegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    if (navigationAction.targetFrame == nil) {
        if (self.needSetCookie) {
            [webView loadRequest:[self fixRequest:navigationAction.request]];
        } else {
            [webView loadRequest:navigationAction.request];
        }
    }
    decisionHandler(WKNavigationActionPolicyAllow);
}

- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation {
}

- (void)webView:(WKWebView *)webView decidePolicyForNavigationResponse:(WKNavigationResponse *)navigationResponse decisionHandler:(void (^)(WKNavigationResponsePolicy))decisionHandler {
    decisionHandler(WKNavigationResponsePolicyAllow);
}

- (void)webView:(WKWebView *)webView didCommitNavigation:(WKNavigation *)navigation {
}

- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
}

- (void)webView:(WKWebView *)webView didFailProvisionalNavigation:(WKNavigation *)navigation {
}

- (void)webView:(WKWebView *)webView didReceiveServerRedirectForProvisionalNavigation:(WKNavigation *)navigation {
}

- (void)webView:(WKWebView *)webView didFailNavigation:(WKNavigation *)navigation withError:(NSError *)error {
}

- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView {
    [webView reload];
}

- (void)webViewDidClose:(WKWebView *)webView {
}

//加载不受信任的https
- (void)webView:(WKWebView *)webView didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        NSURLCredential *card = [[NSURLCredential alloc]initWithTrust:challenge.protectionSpace.serverTrust];
        completionHandler(NSURLSessionAuthChallengeUseCredential,card);
    }
}

#pragma mark - WKScriptMessageHandler
#pragma mark - JS调用OC的处理
- (void)userContentController:(WKUserContentController *)userContentController
      didReceiveScriptMessage:(WKScriptMessage *)message {
    if ([message.name isEqualToString:@"gotoActivity"]) {
        NSDictionary *converet = message.body;
        NSString *type = kStringFormat(@"%@", [converet safe_objectForKey:@"type"]);
        NSString *exist = kStringFormat(@"%@", [converet safe_objectForKey:@"close"]);
        if ([exist isEqualToString:@"true"]) {
            NSArray *viewcontrollers = [UIViewController currentNavigatonController].viewControllers;
            if (viewcontrollers.count > 1 && [viewcontrollers objectAtIndex:viewcontrollers.count - 1] == [UIViewController currentViewController]) {
                [[UIViewController currentNavigatonController] popViewControllerAnimated:YES];
            } else {
                [[UIViewController currentViewController] dismissViewControllerAnimated:YES completion:nil];
            }
        }
        if ([type isEqualToString:@"充值"]) {
            XMRechargeViewController *vc = [[XMRechargeViewController alloc] initWithNibName:kStringFromClass(XMRechargeViewController) bundle:nil];
            [self.navigationController pushViewController:vc animated:YES];
        } else if ([type isEqualToString:@"认证"]) {
            XMRealViewController *vc = [[XMRealViewController alloc] initWithNibName:kStringFromClass(XMRealViewController) bundle:nil];
            [self.navigationController pushViewController:vc animated:YES];
        } else if ([type isEqualToString:@"客服"]) {
            //            [self yh_openURL:YHRouterWebServicePage routerParameters:@{@"url": kGlobalVariables.appConfig.customer_service, @"nav": @(NO)} sourceViewController:nil];
        } else if ([type isEqualToString:@"邀请"]) {
            XMInviteViewController *vc = [[XMInviteViewController alloc] initWithNibName:kStringFromClass(XMInviteViewController) bundle:nil];
            [self.navigationController pushViewController:vc animated:YES];
        } else if ([type isEqualToString:@"任务"]) {
            XMTaskViewController *vc = [[XMTaskViewController alloc] init];
            [self.navigationController pushViewController:vc animated:YES];
        } else if ([type isEqualToString:@"绑定手机"]) {
            if (kUserModel.mobile.length > 0) {
                [MBProgressHUD showHUDMsg:@"手机号码已绑定" toView:nil];
                return;
            }
            XMBindPhoneLoginViewController *vc = [[XMBindPhoneLoginViewController alloc] initWithNibName:kStringFromClass(XMBindPhoneLoginViewController) bundle:nil];
            [self.navigationController pushViewController:vc animated:YES];
        } else if ([type isEqualToString:@"亲密度"]) {
            XMIntimacyViewController *vc = [[XMIntimacyViewController alloc] init];
            [self.navigationController pushViewController:vc animated:YES];
        }
    }
}

- (void)webView:(WKWebView *)webView runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)defaultText initiatedByFrame:(WKFrameInfo *)frame completionHandler:(void (^)(NSString *_Nullable))completionHandler {
    if ([prompt isEqualToString:@"obtainUserToken"]) {
        completionHandler([XMLoginManager sharedInstance].token);
    }
    if ([prompt containsString:@"_"] && [prompt containsString:@"encryptHttpParams"]) {
        NSArray *arr = [prompt componentsSeparatedByString:@"_"];
        NSString *timestamp = kStringFormat(@"timestamp=%@", [NSDate xm_getCurrentTimeIntervalWithLenght:13]);
        NSString *parm = @"";
        NSMutableDictionary *paramDic = @{}.mutableCopy;
        NSString *temp = [arr safe_objectAtIndex:1];
        if (temp.length > 0) {
            parm = kStringFormat(@"%@&%@", temp, timestamp);
        } else {
            parm = timestamp;
        }
        NSString *aesKey = [YHAESHelper getRandomNumberString];
        NSString *content = [YHAESHelper aesEncryptString:parm publicKey:aesKey];
        NSString *requestPubKeyPath = [[NSBundle mainBundle] pathForResource:@"webpublic.pem" ofType:nil];
        NSString *signature = [YHRSAHelper encrypt:aesKey keyFilePath:requestPubKeyPath];
        [paramDic safeSetObject:content forKey:@"content"];
        [paramDic safeSetObject:signature forKey:@"signature"];
        NSLog(@"paramDic: %@", [paramDic jsonStringEncoded]);
        completionHandler([paramDic jsonStringEncoded]);
    }
}

#pragma mark - KVO 方法
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
    if ([keyPath isEqualToString:@"title"]) {
        NSString *title = (NSString *)[change objectForKey:NSKeyValueChangeNewKey];
        if (self.needChangeTitle) {
            self.navTitleLa.text = title;
        }
    }
    if ([keyPath isEqualToString:@"URL"]) {
        NSLog(@"%@", self.webView.URL);
    }
    if ([keyPath isEqualToString:@"estimatedProgress"]) {
        CGFloat newprogress = [[change objectForKey:NSKeyValueChangeNewKey] doubleValue];
        if (newprogress == 1) {
            [self.progressView setProgress:newprogress];
            __weak typeof(self) weakSelf = self;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 0.3 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{
                weakSelf.progressView.alpha = 0.0;
            });
        } else {
            [self.progressView setProgress:newprogress];
            self.progressView.alpha = 1.0;
        }
    }
}

#pragma mark - Cookies
- (void)updateWebViewCookie {
    WKUserScript *cookieScript = [[WKUserScript alloc] initWithSource:[self cookieString] injectionTime:WKUserScriptInjectionTimeAtDocumentStart forMainFrameOnly:NO];
    [self.webView.configuration.userContentController addUserScript:cookieScript];
}

- (NSURLRequest *)fixRequest:(NSURLRequest *)request {
    NSMutableURLRequest *fixedRequest;
    if ([request isKindOfClass:[NSMutableURLRequest class]]) {
        fixedRequest = (NSMutableURLRequest *)request;
    } else {
        fixedRequest = request.mutableCopy;
    }
    
    NSDictionary *dict = [NSHTTPCookie requestHeaderFieldsWithCookies:[NSHTTPCookieStorage sharedHTTPCookieStorage].cookies];
    if (dict.count) {
        NSMutableDictionary *mDict = [NSMutableDictionary dictionaryWithDictionary:request.allHTTPHeaderFields];
        [mDict setValuesForKeysWithDictionary:dict];
        fixedRequest.allHTTPHeaderFields = mDict;
    }
    return fixedRequest;
}

- (NSString *)cookieString {
    NSMutableString *script = [NSMutableString string];
    for (NSHTTPCookie *cookie in [[NSHTTPCookieStorage sharedHTTPCookieStorage] cookies]) {
        if ([cookie.value rangeOfString:@"'"].location != NSNotFound) {
            continue;
        }
        [script appendFormat:@"document.cookie='%@'; \n", cookie.javascriptString];
    }
    return script;
}

- (void)clearCache {
    NSSet *websiteDataTypes = [WKWebsiteDataStore allWebsiteDataTypes];
    NSDate *dateFrom = [NSDate dateWithTimeIntervalSince1970:0];
    [[WKWebsiteDataStore defaultDataStore] removeDataOfTypes:websiteDataTypes modifiedSince:dateFrom completionHandler:^{}];
}

#pragma mark - Getter
- (UIProgressView *)progressView {
    if (_progressView == nil) {
        UIProgressView *progressView = [[UIProgressView alloc] initWithFrame:CGRectMake(0, self.needNav ? kNavBarAndStatusBarHeight : kStatusBarHeight, kScreenWidth, 1)];
        progressView.frame = CGRectMake(0, self.needNav ? kNavBarAndStatusBarHeight : kStatusBarHeight, kScreenWidth, 1);
        CGAffineTransform transform;
        transform = CGAffineTransformMakeScale(1.0f, 1.0f);
        if (@available(iOS 14, *)) {
            progressView.frame = CGRectMake(0, (self.needNav ? kNavBarAndStatusBarHeight : kStatusBarHeight) - 1, kScreenWidth, 1);
            transform = CGAffineTransformMakeScale(1.0f, .5f);
        }
        progressView.trackTintColor = [UIColor clearColor];
        progressView.progressTintColor = kAppMainColor;
        progressView.transform = transform;
        progressView.trackImage = [UIImage imageWithColor:kAppMainColor];
        progressView.contentMode = UIViewContentModeScaleAspectFill;
        progressView.layer.cornerRadius = 1.0;
        progressView.layer.masksToBounds = YES;
        [progressView setProgress:0.1 animated:YES];
        _progressView = progressView;
    }
    return _progressView;
}

- (WKWebView *)webView {
    if (_webView == nil) {
        WKWebViewConfiguration *config = [[WKWebViewConfiguration alloc] init];
        config.userContentController = [[WKUserContentController alloc] init];
        config.preferences = [[WKPreferences alloc] init];
        config.preferences.minimumFontSize = 12;
        config.preferences.javaScriptEnabled = YES;
        config.processPool = [[WKProcessPool alloc] init];
        _webView = [[WKWebView alloc] initWithFrame:CGRectMake(0, self.needNav ? kNavBarAndStatusBarHeight : kStatusBarHeight, self.view.frame.size.width, self.view.frame.size.height - (self.needNav ? kNavBarAndStatusBarHeight : kStatusBarHeight)) configuration:config];
        _webView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
        _webView.backgroundColor = [UIColor whiteColor];
        _webView.navigationDelegate = self;
        _webView.UIDelegate = self;
        _webView.allowsBackForwardNavigationGestures = YES;
        _webView.allowsLinkPreview = YES;
        _webView.scrollView.bounces = NO;
        _webView.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal;
        [_webView setMultipleTouchEnabled:YES];
        [_webView setAutoresizesSubviews:YES];
        [_webView.scrollView setAlwaysBounceVertical:YES];
        
        [_webView addObserver:self
                   forKeyPath:@"title"
                      options:NSKeyValueObservingOptionNew
                      context:nil];
        [_webView addObserver:self
                   forKeyPath:@"URL"
                      options:NSKeyValueObservingOptionNew
                      context:nil];
        [_webView addObserver:self forKeyPath:@"estimatedProgress" options:NSKeyValueObservingOptionNew context:nil];
    }
    return _webView;
}

@end
